#ifndef _SFS_SERVER_FRAME_WORK_H_
#define _SFS_SERVER_FRAME_WORK_H_

#include <list>
#include <string>

#include <log4cxx/logger.h>

#include <event2/event.h>

using std::list;
using std::string;

using namespace log4cxx;

typedef int (*HANDLE_SOCKET_INPUT_FUNC)(int fd, void *arg);
typedef int (*THREAD_INIT_FUNC)(void *arg);

class ServerFrameWork {

public:
	int init_logger(const char* log_cnf_file);

	int init(int thread_number,  HANDLE_SOCKET_INPUT_FUNC func, void * arg, \
			const char * listen_ip,  unsigned short listen_port, const int socket_idle_timeout, \
			THREAD_INIT_FUNC thread_init_func, void * thread_init_func_arg);
	int start_server();

protected:
	int set_up_listner();
	int run_server_loop();
	static void  listner_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *address, \
			int socklen,  void *ctx);
	static void  socket_event_cb(evutil_socket_t fd, short events, void * arg);

	static void * worker_thread_routine(void * arg);

	int add_active_socket(int fd);
	int pop_active_socket();
	int handle_socket_idle_timeout(int fd);
	int add_socket_to_event_base(int fd);
private:
	string _log_cnf_file;
	static LoggerPtr _logger;
	struct event_base * _eb;
	int _thread_number;
	HANDLE_SOCKET_INPUT_FUNC _handle_socket_input_func;
	void * _handle_socket_input_func_arg;
	string _listen_ip;
	unsigned short _listen_port;
	struct evconnlistener * _listner;
	int _socket_idle_timeout;
	list<int> _active_sockets;
	pthread_mutex_t _active_sockets_mutex;
	THREAD_INIT_FUNC _thread_init_func;
	void * _thread_init_func_arg;
	pthread_cond_t _worker_thread_wake_up_cond;
};

#endif
